/**
 * 
 */
package com.game.data.dao.example;

import java.util.List;

import org.bson.types.ObjectId;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.geo.Box;
import org.springframework.data.mongodb.core.geo.Circle;
import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.data.mongodb.repository.MongoRepository;

import com.game.model.example.Person;
import com.game.model.example.ZipCode;

/**
 * <li>通过继承{@link MongoRepository}接口，
 * 我们可以非常方便地实现对一个对象的增删改查.
 * 要使用Repository的功能，先继承MongoRepository<T, TD>接口，
 * 其中T为仓库保存的bean类，TD为该bean的唯一标识的类型，一般为ObjectId。
 * 之后在service中注入该接口就可以使用，无需实现里面的方法，spring会根据定义的规则自动生成。
 * <br>
 * <li>但是{@link MongoRepository}实现了的只是最基本的增删改查的功能，
 * 要想增加额外的查询方法，可以按照以下规则定义接口的方法。<br>
 * 自定义查询方法，格式为“findBy+字段名+方法后缀”，
 * 方法传进的参数即字段的值，此外还支持分页查询，通过传进一个Pageable对象，返回Page集合。
 * @author Quake
 *
 */
public interface PersonDAO extends MongoRepository<Person, ObjectId>, PersonDAOCustom {
	//例1:分页查询
	/** 是 IS */
	public Page<Person> findByAge(int age, Pageable pageable);
	public Page<Person> findByAgeIs(int age, Pageable pageable);
	/** 非  Not  */
	public Page<Person> findByAgeNot(int age, Pageable pageable);
	/** 大于 GreaterThan  {"age" : {"$gt" : age}} */
	public Page<Person> findByAgeGreaterThan(int age, Pageable pageable);
	/** 小于  LessThan 	{"age" : {"$lt" : age}} */
	public Page<Person> findByAgeLessThan(int age, Pageable pageable);
	/** 模糊查询 Like  {"age" : age} ( age as regex) */
	public Page<Person> findByFirstNameLike(String name, Pageable pageable);
	/** 在...之间  Between */
	public Page<Person> findByAgeBetween(int from, int to, Pageable pageable); 
	/** 非空 NotNull */
	public Page<Person> findByFirstNameNotNull(Pageable pageable);
	/** 为空 IsNull */
	public Page<Person> findByFirstNameNull(Pageable pageable);
	/** 查询地理位置相近的 Near {"location" : {"$near" : [x,y]}}  */
//	public Page<Person> findByLocationNear(Point point, Pageable pageable); 
	/** 在地理位置范围内的 Within  {"location" : {"$within" : {"$center" : [ [x, y], distance]}}}  */
//	public Page<Person> findByLocationWithin(Circle circle, Pageable pageable);
	/** 在地理位置范围内的Within {"location" : {"$within" : {"$box" : [ [x1, y1], x2, y2]}}}  */
//	public Page<Person> findByLocationWithin(Box box, Pageable pageable);
	//例2:非分页查询 
	List<Person> findByAge(int age);
	//例3:且    And
	List<Person> findByAgeAndSsn(int age, int ssn);
	//例4:或   Or
	List<Person> findByAgeOrSsn(int age, int ssn);
	//例5:Distinct 还没弄明白...待深入测试
	List<Person> findDistinctPeopleByLastNameOrFirstName(String lastName, String firstName);
	List<Person> findPeopleDistinctByLastNameOrFirstName(String lastName, String firstName);
	List<Person> findDistinctPeopleByLastName(String lastName);
	
	List<Person> findByLastNameOrFirstName(String lastName, String firstName);
	//例6：IgonreCase 忽略大小写?  待测
	List<Person> findByLastNameIgnoreCase(String lastName);
	//AllIgonreCase  待测
	List<Person> findByLastNameAndFirstNameAllIgnoreCase(String lastName, String firstName);
	//例7: ORDER BY 排序
	List<Person> findByLastNameOrderByFirstNameAsc(String lastname);
	List<Person> findByLastNameOrderByFirstNameDesc(String lastname);
	//例8: 内嵌属性查询  :address.zipCode
	List<Person> findByAddressZipCode(ZipCode zipCode);
	List<Person> findByAddress_ZipCode(ZipCode zipCode);
	
}
